// 导入全局设置和环境变量加载
import "./global" // 导入全局变量设置
import "./src/lib/load-env" // 导入环境变量加载

// 导入 Node.js 核心模块
import os from "node:os"

// 导入第三方库
import middie from "@fastify/middie" // Fastify 中间件插件
import { fastifyRequestContext } from "@fastify/request-context" // 请求上下文插件
import { env } from "@follow/shared/env.ssr" // 环境变量
import type { FastifyRequest } from "fastify" // Fastify 请求类型
import Fastify from "fastify" // Fastify Web 框架
import { nanoid } from "nanoid" // 生成唯一 ID
import { FetchError } from "ofetch" // HTTP 请求错误类型

// 导入自定义模块
import { MetaError } from "~/meta-handler" // 元数据处理错误

import { globalRoute } from "./src/router/global" // 全局路由处理
import { ogRoute } from "./src/router/og" // Open Graph 路由处理

// 判断是否在 Vercel 环境
const isVercel = process.env.VERCEL === "1"

// 扩展请求上下文接口
declare module "@fastify/request-context" {
  interface RequestContextData {
    req: FastifyRequest // 当前请求对象
    upstreamEnv: "prod" | "dev" // 上游环境
    upstreamOrigin: string // 上游源地址
  }
}

// 创建 Fastify 应用实例的函数
export const createApp = async () => {
  // 初始化 Fastify 应用
  const app = Fastify({})

  // 注册请求上下文插件
  app.register(fastifyRequestContext)
  // 注册中间件插件，钩子设置为 "onRequest"
  await app.register(middie, {
    hook: "onRequest",
  })

  // 设置错误处理程序
  app.setErrorHandler(function (err, req, reply) {
    this.log.error(err) // 记录错误日志
    const traceId = nanoid(8) // 生成错误追踪 ID

    // 根据错误类型返回不同的响应
    if (err instanceof FetchError) {
      reply
        .status((err as FetchError).response?.status || 500)
        .send({ ok: false, traceId, message: err.message })
    } else if (err instanceof MetaError) {
      reply.status(err.status).send({ ok: false, traceId, message: err.metaMessage })
    } else {
      const message = err.message || "Internal Server Error"
      const status = Number.parseInt(err.code as string) || 500
      reply.status(status).send({ ok: false, message, traceId })
    }
  })

  // 添加请求钩子，设置请求上下文
  app.addHook("onRequest", (req, reply, done) => {
    req.requestContext.set("req", req) // 存储请求对象到上下文

    const { host } = req.headers
    const forwardedHost = req.headers["x-forwarded-host"]
    const finalHost = forwardedHost || host

    // 根据主机名判断上游环境
    const upstreamEnv = finalHost?.includes("dev") ? "dev" : "prod"
    if (!__DEV__) req.requestContext.set("upstreamEnv", upstreamEnv)

    // 设置上游源地址
    if (upstreamEnv === "prod") {
      req.requestContext.set("upstreamOrigin", env.VITE_WEB_PROD_URL || env.VITE_WEB_URL)
    } else {
      req.requestContext.set("upstreamOrigin", env.VITE_WEB_DEV_URL || env.VITE_WEB_URL)
    }
    reply.header("x-handled-host", finalHost) // 添加处理主机头
    done()
  })

  // 开发环境下注册 Vite 开发服务器
  if (__DEV__) {
    const devVite = await import("./src/lib/dev-vite")
    await devVite.registerDevViteServer(app)
  }

  // 注册路由
  ogRoute(app) // 注册 Open Graph 路由
  globalRoute(app) // 注册全局路由

  return app
}

// 非 Vercel 环境下启动服务器
if (!isVercel) {
  createApp().then(async (app) => {
    // 启动服务器监听 2234 端口
    await app.listen({ port: 2234, host: "0.0.0.0" })
    console.info("Server is running on http://localhost:2234")
    const ip = getIPAddress() // 获取本机 IP 地址

    if (ip) console.info(`Server is running on http://${ip}:2234`)
  })
}

// 获取本机 IP 地址的辅助函数
function getIPAddress() {
  const interfaces = os.networkInterfaces() // 获取网络接口
  for (const devName in interfaces) {
    const iface = interfaces[devName]

    for (const alias of iface || []) {
      // 返回第一个非本地 IPv4 地址
      if (alias.family === "IPv4" && alias.address !== "127.0.0.1" && !alias.internal)
        return alias.address
    }
  }
  return "0.0.0.0"
}
